﻿using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace ZOIL.DataBackend.BaseX.XQueries
{
    internal static class XQueriesLoader
    {
        private static readonly Assembly Assembly;
        private static readonly string Namespace;

        static XQueriesLoader()
        {
            Assembly = typeof(XQueriesLoader).Assembly;
            Namespace = typeof(XQueriesLoader).Namespace;
        }

        private static string LoadXQuery(string name)
        {
            var path = string.Format("{0}.{1}.template.xq", Namespace, name);

            using (var stream = Assembly.GetManifestResourceStream(path))
            {
                if (stream == null)
                    throw new Exception(string.Format("Could not load resource at {0}", path));

                var template = new StringBuilder();

                using (var reader = new StreamReader(stream))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line.StartsWith("//") || line.Trim().Length <= 0)
                            continue;

                        template.AppendLine(line);
                    }
                    return template.ToString();
                }
            }
        }

        #region AllocateIdQuery

        private static readonly Lazy<string> AllocateIdQuery = new Lazy<string>(() => LoadXQuery("AllocateIdQuery"));

        /// <summary>
        ///     Query to allocate an id from the database
        ///     File: AllocateIdQuery.template.xq
        /// </summary>
        internal static string GetAllocateIdQuery(string databaseName)
        {
            return string.Format(AllocateIdQuery.Value, databaseName);
        }

        #endregion

        #region StoreObjectPairQuery

        private static readonly Lazy<string> StoreObjectPairQuery = new Lazy<string>(() => LoadXQuery("StoreObjectPairQuery"));

        /// <summary>
        ///     Query to store a Object-VisualProperties Pair
        ///     File: StoreObjectPairQuery.template.xq
        /// </summary>
        internal static string GetStoreObjectPairQuery(string databaseName, string eventName, string eventType, long id, string objPath,
                                                       XElement objXml, string propPath, XElement propXml)
        {
            return string.Format(StoreObjectPairQuery.Value, databaseName, eventName, eventType, id, objPath, objXml, propPath, propXml);
        }

        #endregion

        #region SaveChangeInDatabaseQuery

        private static readonly Lazy<string> SaveChangeQuery = new Lazy<string>(() => LoadXQuery("SaveChangeQuery"));

        /// <summary>
        ///     Query to store a Object-VisualProperties Pair
        ///     File: StoreObjectPairQuery.template.xq
        /// </summary>
        internal static string GetSaveChangerQuery(string databaseName, string documentName, XElement objXml, string idPropertyName)
        {
            return string.Format(SaveChangeQuery.Value, databaseName, documentName, objXml, idPropertyName);
        }

        #endregion

        #region LoadObjectPairByIdQuery

        private static readonly Lazy<string> LoadObjectPairByIdQuery = new Lazy<string>(() => LoadXQuery("LoadObjectPairByIdQuery"));

        /// <summary>
        ///     Query to store a Object-VisualProperties Pair
        ///     File: StoreObjectPairQuery.template.xq
        /// </summary>
        internal static string GetLoadObjectPairByIdQuery(long id, string idPropertyNameInDatabaseObject, string idPropertyNameInVisualProperties)
        {
            return string.Format(LoadObjectPairByIdQuery.Value, id, idPropertyNameInDatabaseObject, idPropertyNameInVisualProperties);
        }

        #endregion

        #region LoadByXQueryQuery

        private static readonly Lazy<string> LoadByXQueryQuery = new Lazy<string>(() => LoadXQuery("LoadByXQueryQuery"));

        internal static string GetLoadByXQueryQuery(string idPropertyNameInDatabaseObject, string idPropertyNameInVisualProperties)
        {
            return string.Format(LoadByXQueryQuery.Value, idPropertyNameInDatabaseObject, idPropertyNameInVisualProperties);
        }

        #endregion

        #region DeleteObjectPairQuery

        private static readonly Lazy<string> DeleteObjectPairByIdQuery = new Lazy<string>(() => LoadXQuery("DeleteObjectPairByIdQuery"));

        internal static string GetDeleteObjectPairByIdQuery(long id, string idPropertyNameInDatabaseObject, string idPropertyNameInVisualProperties)
        {
            return string.Format(DeleteObjectPairByIdQuery.Value, id, idPropertyNameInDatabaseObject, idPropertyNameInVisualProperties);
        }

        #endregion
    }
}